/**
 * @description array to tree
 */

interface IArrayItem {
    id: number;
    name: string;
    parentId: number;
}

interface ITreeNode {
  id: number;
  name: string;
  children?: Array<ITreeNode>
}

function convert(arr: IArrayItem[]): ITreeNode | null{
  let tree = <ITreeNode | null>null;
 
  const idMapTreeNode: Map<number, ITreeNode> = new Map();
//   arr.forEach((item) => {
//     const {id, name} = item;
//     idMapTreeNode.set(id, {id, name});
//   });

  const orderedByParentIdArray = arr.sort((a, b) => (a.parentId - b.parentId));

  orderedByParentIdArray.forEach(item => {
    const { id, name, parentId } = item;
    const treeNode = { id, name };
    idMapTreeNode.set(id, treeNode);
    const parentNode = idMapTreeNode.get(parentId);
    if(parentNode) {
        if(parentNode.children == null) { 
            parentNode.children = [];
        }
        parentNode.children.push(treeNode)
    }
    if(parentId === 0){
        tree = treeNode;
    }
  })

  return tree;
}

const arr = [
    {id: 1, name: 'businessPart_1', parentId: 0},
    {id: 2, name: 'businessPart_2', parentId: 3},
    {id: 3, name: 'businessPart_3', parentId: 2},
    {id: 4, name: 'businessPart_4', parentId: 3},
    // {id: 5, name: 'businessPart_5', parentId: 4},
    // {id: 6, name: 'businessPart_6', parentId: 3},
    // {id: 7, name: 'businessPart_7', parentId: 6},
];

console.log(convert(arr));